package com.yss.sofa.report.engine.core;

import java.io.Serializable;

import com.yss.sofa.report.engine.Const;
import com.yss.sofa.report.engine.cell.visible.extendable.ExtendableCell;
import com.yss.sofa.report.engine.cell.visible.result.ResultCell;
import com.yss.sofa.report.engine.util.NumberUtil;

public class Block implements Serializable{
	private static final long serialVersionUID = -5317030448321928726L;
	/**
	 * 刀的方向
	 */
	public static enum Split{
		IGNORE,
		VERTICAL,
		HORIZONTAL,
	}
	public Split split;
	public int move;
	public int top;
	public int left;
	public int rowCount;
	public int colCount;
	public ResultCell[][] data;
	public void print(){
		System.out.println("*****************************************");
		for(int r=0;r<rowCount;r++){
			for(int c=0;c<colCount;c++){
				ResultCell cell=data[r][c];
				String v=(cell==null)?null:cell.getValue();
				System.out.print(v);
				System.out.print("\t");
			}
			System.out.print("\n");
		}
		System.out.println("*****************************************");
	}
	public static Block SingleBlock(ResultCell cell) throws Exception{
		Block block=new Block(cell.getTop(),cell.getLeft(),cell.getRowInc(),cell.getColInc(),cell.getMove(),Split.IGNORE);
		block.fill(cell);
		return block;
	}
	public static Block ExtendableBlock(ExtendableCell cell,int dataCount,int fieldCount) throws Exception{
		//TODO: 只有sheet[main]中才有ExtendableCell，所以抛的异常直接写死了，应该把sheet传进来，但只为了异常而加一个参数，是否值得？
		if(dataCount<=0){
			dataCount=1;
		}
		if(fieldCount<=0){
			fieldCount=1;
		}
		int top=cell.getTop();
		int left=cell.getLeft();
		int move=cell.getMove();
		int extend=cell.getExtend();
		Split split=Split.IGNORE;
		switch (move) {
		case Const.CELL_MOVE_ABS:
		case Const.CELL_MOVE_RIGHT:
		case Const.CELL_MOVE_BOTTOM:
			break;
		case Const.CELL_MOVE_INFER:{
			switch (extend) {
			case Const.CELL_EXTEND_BOTTOM:
			case Const.CELL_EXTEND_RIGHT_BOTTOM:
				move=Const.CELL_MOVE_BOTTOM;
				break;
			case Const.CELL_EXTEND_RIGHT:
			case Const.CELL_EXTEND_BOTTOM_RIGHT:
				move=Const.CELL_MOVE_RIGHT;
				break;
			case Const.CELL_EXTEND_NONE:
				move=Const.CELL_MOVE_ABS;
				break;
			default:
				throw new Exception("无法根据sheet[main].cell["+NumberUtil.toExcelPoint(cell.getRfrom(), cell.getCfrom())+"].extend["+cell.getExtend()+"]推断出move属性");
			}
			break;
		}
		default:
			throw new Exception("sheet[main].cell["+NumberUtil.toExcelPoint(cell.getRfrom(), cell.getCfrom())+"].move["+cell.getMove()+"]值无效");
		}
		int rowCount,colCount;
		switch (extend) {
		case Const.CELL_EXTEND_NONE:
			rowCount=cell.getRowInc();
			colCount=cell.getColInc();
			break;
		case Const.CELL_EXTEND_RIGHT:
			if(cell.getSkip()>0){
				split=Split.VERTICAL;
			}
			rowCount=cell.getRowInc();
			colCount=(cell.getColInc()+cell.getSkip())*dataCount;
			break;
		case Const.CELL_EXTEND_BOTTOM:
			if(cell.getSkip()>0){
				split=Split.HORIZONTAL;
			}
			rowCount=(cell.getRowInc()+cell.getSkip())*dataCount;
			colCount=cell.getColInc();
			break;
		case Const.CELL_EXTEND_RIGHT_BOTTOM:
			if(cell.getSkip()>0){
				split=Split.HORIZONTAL;
			}
			rowCount=(cell.getRowInc()+cell.getSkip())*dataCount;
			colCount=cell.getColInc()*fieldCount;
			break;
		case Const.CELL_EXTEND_BOTTOM_RIGHT:
			if(cell.getSkip()>0){
				split=Split.VERTICAL;
			}
			rowCount=cell.getRowInc()*fieldCount;
			colCount=(cell.getColInc()+cell.getSkip())*dataCount;
			break;
		default:
			throw new Exception("sheet[main].cell["+NumberUtil.toExcelPoint(cell.getRfrom(), cell.getCfrom())+"].extend["+cell.getExtend()+"]值无效");
		}
		cell.setMove(move);
		return new Block(top,left,rowCount,colCount,move,split);
	}
	public Block(int top,int left,int rowCount,int colCount,int move,Split split){
		this.move=move;
		this.top=top;
		this.left=left;
		this.rowCount=rowCount;
		this.colCount=colCount;
		this.split=split;
		data=new ResultCell[rowCount][colCount];
	}
	public void fill(ResultCell cell) throws Exception{
		for(int r=cell.getRbegin();r<=cell.getRend();r++){
			for(int c=cell.getCbegin();c<=cell.getCend();c++){
				if(r>=rowCount || c>=colCount){
					throw new Exception("test:point["+r+","+c+"]超出block["+top+","+left+"]的初始范围");
				}
				if(data[r][c]!=null){
					throw new Exception("test:无法覆盖block["+top+","+left+"]中的point["+r+","+c+"]");
				}
				data[r][c]=cell;
			}
		}
	}
	public int getRight(){
		return left+colCount-1;
	}
	public int getBottom(){
		return top+rowCount-1;
	}
}
